<template>
  <a-upload
    @beforeUpload="beforeUpload"
    :custom-request="customRequest"
    :accept="fileTypeList.join(',')"
    :listType="listType"
    :limit="limit"
    v-bind="args ? { ...args } : null"
    :draggable="draggable"
    :show-remove-button="isShowRemove"
    v-model:fileList="uploadList"
    :disabled="disabled"
  >
    <template #extra-button="{ fileItem }" v-if="listType === 'text'">
      <a-space style="margin-left: 10px">
        <a-link @click="preview(fileItem.url)">预览</a-link>
        <a-link @click="preview(fileItem.url)">下载</a-link>
      </a-space>
    </template>
  </a-upload>
</template>

<script setup lang="ts">
  import {
    reactive,
    onMounted,
    ref,
    nextTick,
    computed,
    watchEffect,
    watch,
  } from 'vue';
  import { FileUpload } from '@/utils/upload';
  import { Message } from '@arco-design/web-vue';
  import { cloneDeep } from 'lodash';
  import { ajaxService } from '@/utils/request';

  export interface TFileItem {
    id?: number;
    fileUrl: string;
    fileName?: string;
    uid?: string;
    sourceAddr?: string;
  }

  const props = withDefaults(
    defineProps<{
      fileList: TFileItem[];
      fileTypeList?: string[];
      maxSize?: number;
      limit?: number;
      draggable?: boolean;
      isShowRemove?: boolean;
      args?: any; // 对象，放置a-upload的剩余属性
      disabled?: boolean;
      listType?: 'picture' | 'text' | 'picture-card';
    }>(),
    {
      fileTypeList: () => [],
      listType: 'text',
      limit: 1,
      maxSize: 10 * 1024 * 1024,
      isShowRemove: true,
    }
  );

  const uploadList = ref<any[]>([]);
  let refresh = () => {
    uploadList.value = [];
  };
  defineExpose({ refresh });

  const setUploadList = () => {
    const list = cloneDeep(uploadList.value);
    props.fileList.forEach((item) => {
      const { id, fileUrl, fileName, uid, sourceAddr } = item;
      if (
        !list.some(
          (upload: any) =>
            uid === upload.uid ||
            fileUrl === upload.url ||
            fileUrl === upload?.response?.fileUrl
        )
      ) {
        uploadList.value.push({
          id,
          name: fileName,
          status: 'done',
          url: fileUrl,
          response: { fileUrl, fileName, sourceAddr },
        });
      }
    });
  };
  let preview = async (url: string) => {
    const res = await ajaxService({
      url,
      method: 'get',
      responseType: 'blob',
      baseURL: '',
    });
    const file = new Blob([res], { type: 'application/pdf' });
    const changeUrl = window.webkitURL.createObjectURL(file);
    window.open(changeUrl);
  };
  watch(
    () => props.fileList,
    () => setUploadList()
  );
  setUploadList();
  const emit = defineEmits(['update:fileList', 'beforeRemove']);
  watch(
    () => uploadList.value,
    () => {
      nextTick(() => {
        uploadList.value.forEach((item) => {
          item.url = item.response?.fileUrl;
        });
        emit(
          'update:fileList',
          uploadList.value
            .filter(({ status }) => status === 'done')
            .map((item: any) => {
              return {
                id: item.id,
                uid: item.uid,
                fileUrl: item.response?.fileUrl,
                fileName: item.response?.fileName,
                sourceAddr: item.response?.sourceAddr,
              };
            })
        );
      });
    }
  );
  // 上传前校验
  const beforeUpload = async (file: File) => {
    const { maxSize, fileTypeList } = props;
    if (maxSize && file.size > maxSize) {
      Message.warning(`文件过大,不可超过${(maxSize / 1048576).toFixed(2)}M`);
      return Promise.reject();
    }
    const fileType = file.name.slice(file.name.lastIndexOf('.') + 1);
    const fileName = file.name.slice(0, file.name.lastIndexOf('.'));
    // if (fileTypeList.length && !fileTypeList.includes(fileType)) {
    //   Message.warning(`${fileName}文件类型错误`);
    //   return Promise.reject();
    // }
    if (fileTypeList.length) {
      const lowercaseFileTypeList = fileTypeList.map((type) =>
        type.toLowerCase()
      );
      const lowercaseFileType = fileType.toLowerCase();

      if (!lowercaseFileTypeList.includes(lowercaseFileType)) {
        Message.warning(`${fileName}文件类型错误`);
        return Promise.reject();
      }
    }
    return Promise.resolve(file);
  };
  const customRequest = (option: any) => {
    const { onError, onSuccess, fileItem } = option;
    const formData = new FormData();
    formData.append('data', fileItem.file);
    FileUpload(formData)
      .then((res: any) => {
        onSuccess({
          fileUrl: res.data.data.addr,
          fileName: fileItem.name,
          sourceAddr: res.data.data.sourceAddr,
          url: res.data.data.addr,
        });
      })
      .catch((err) => onError(err));
    return {
      abort: () => {
        //
      },
    };
  };
</script>

<style scoped></style>
